Перейти к основному содержимому

Дополнительная статья

Параметры командной строки

Что такое параметры командной строки

Когда вы запускаете программу из терминала, вы можете передать ей дополнительные данные — параметры командной строки. Это позволяет программе получать информацию извне и работать с разными входными данными.

# Примеры запуска программ с параметрами
./program file.txt
./calculator 5 + 3
gcc -o hello source.c

Функция main с параметрами

Функция main может получать значения извне при запуске программы. Для этого она имеет специальную форму записи:

int main(int argc, char *argv[])
{
// код программы
return 0;
}

Параметры функции main

int argc — argument count (количество аргументов)

  • Хранит общее количество переданных аргументов
  • Минимальное значение = 1 (имя программы всегда есть)
  • Если программе не передали никаких данных, argc равен 1
// При запуске: ./program
// argc = 1

// При запуске: ./program hello world
// argc = 3

Базовый пример

Выведем все аргументы из массива argv на консоль:

#include <stdio.h>

int main(int argc, char *argv[])
{
for (int i = 0; i < argc; i++)
{
printf("%s \n", argv[i]);
}
return 0;
}

Как это работает

Запуск: ./hello

Результат:

./hello

В этом случае argc = 1, а argv[0] = "./hello" — только имя программы.

Практический пример: приветствие пользователей

#include <stdio.h>

int main(int argc, char *argv[])
{
if (argc == 1) {
printf("Привет, неизвестный пользователь!\n");
printf("Использование: %s <имя1> [имя2] [имя3]...\n", argv[0]);
return 0;
}

printf("Привет");
for (int i = 1; i < argc; i++) {
if (i == argc - 1) {
printf(" %s!\n", argv[i]); // Последнее имя с восклицанием
} else {
printf(" %s,", argv[i]); // Остальные через запятую
}
}

return 0;
}

Примеры использования:

./greet                    # Привет, неизвестный пользователь!
./greet Alice # Привет Alice!
./greet Bob Carol Dan # Привет Bob, Carol, Dan!

Работа с числовыми аргументами

Преобразование строк в числа

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
if (argc != 3) {
printf("Калькулятор сложения\n");
printf("Использование: %s <число1> <число2>\n", argv[0]);
return 1;
}

// Преобразуем строки в числа
int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);

int sum = num1 + num2;

printf("%d + %d = %d\n", num1, num2, sum);

return 0;
}

Запуск: ./calc 25 17 Результат: 25 + 17 = 42

Обработка нескольких чисел

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
if (argc < 2) {
printf("Использование: %s <число1> [число2] [число3]...\n", argv[0]);
return 1;
}

int sum = 0;

printf("Складываем числа: ");
for (int i = 1; i < argc; i++) {
int number = atoi(argv[i]);
sum += number;

printf("%d", number);
if (i < argc - 1) printf(" + ");
}

printf(" = %d\n", sum);

return 0;
}

Запуск: ./sum 10 20 30 Результат: Складываем числа: 10 + 20 + 30 = 60

Обработка опций командной строки

Простые опции

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
if (argc < 2) {
printf("Использование: %s [опции] <текст>\n", argv[0]);
printf("Опции:\n");
printf(" -u Преобразовать в верхний регистр\n");
printf(" -l Преобразовать в нижний регистр\n");
return 1;
}

char *text = NULL;
int toUpper = 0, toLower = 0;

// Обрабатываем аргументы
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-u") == 0) {
toUpper = 1;
}
else if (strcmp(argv[i], "-l") == 0) {
toLower = 1;
}
else if (argv[i][0] != '-') {
text = argv[i]; // Это текст, а не опция
}
}

if (text == NULL) {
printf("Ошибка: не указан текст\n");
return 1;
}

printf("Исходный текст: %s\n", text);

if (toUpper) {
printf("Верхний регистр: ");
for (int i = 0; text[i] != '\0'; i++) {
if (text[i] >= 'a' && text[i] <= 'z') {
printf("%c", text[i] - 32);
} else {
printf("%c", text[i]);
}
}
printf("\n");
}

if (toLower) {
printf("Нижний регистр: ");
for (int i = 0; text[i] != '\0'; i++) {
if (text[i] >= 'A' && text[i] <= 'Z') {
printf("%c", text[i] + 32);
} else {
printf("%c", text[i]);
}
}
printf("\n");
}

return 0;
}

Примеры:

./textutil -u Hello        # Верхний регистр: HELLO
./textutil -l WORLD # Нижний регистр: world
./textutil -u -l Test # Оба преобразования

Проверка и валидация аргументов

Проверка корректности данных

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Функция проверки, является ли строка числом
int isValidNumber(char *str) {
if (str == NULL || *str == '\0') {
return 0; // Пустая строка
}

// Пропускаем знак
if (*str == '+' || *str == '-') {
str++;
}

// Проверяем, что остальные символы - цифры
while (*str != '\0') {
if (*str < '0' || *str > '9') {
return 0; // Найден не-цифровой символ
}
str++;
}

return 1; // Строка является числом
}

int main(int argc, char *argv[])
{
if (argc != 3) {
printf("Использование: %s <число1> <число2>\n", argv[0]);
return 1;
}

// Проверяем первый аргумент
if (!isValidNumber(argv[1])) {
printf("Ошибка: '%s' не является числом\n", argv[1]);
return 1;
}

// Проверяем второй аргумент
if (!isValidNumber(argv[2])) {
printf("Ошибка: '%s' не является числом\n", argv[2]);
return 1;
}

int a = atoi(argv[1]);
int b = atoi(argv[2]);

printf("Числа: %d и %d\n", a, b);
printf("Сумма: %d\n", a + b);
printf("Произведение: %d\n", a * b);

return 0;
}

Работа с файлами через аргументы

Программа для чтения файла

#include <stdio.h>
#include <string.h>

void printFileContents(char *filename) {
FILE *file = fopen(filename, "r");

if (file == NULL) {
printf("Ошибка: не могу открыть файл '%s'\n", filename);
return;
}

printf("=== Содержимое файла %s ===\n", filename);

char buffer[1000];
while (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("%s", buffer);
}

printf("\n=== Конец файла ===\n");
fclose(file);
}

int main(int argc, char *argv[])
{
if (argc != 2) {
printf("Программа для чтения файлов\n");
printf("Использование: %s <имя_файла>\n", argv[0]);
return 1;
}

char *filename = argv[1];

// Проверяем расширение файла
int len = strlen(filename);
if (len > 4 && strcmp(filename + len - 4, ".txt") == 0) {
printf("Обрабатываем текстовый файл\n");
}

printFileContents(filename);

return 0;
}

Запуск: ./reader document.txt

Полезные функции для работы с аргументами

Функции преобразования

ФункцияЧто делаетПример
atoi(str)Строка → целое числоint n = atoi("123");
atof(str)Строка → дробное числоdouble d = atof("3.14");
strlen(str)Длина строкиint len = strlen("hello");
strcmp(s1, s2)Сравнение строкif (strcmp(s1, s2) == 0)

Функции сравнения строк

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
if (argc != 2) {
printf("Использование: %s <команда>\n", argv[0]);
printf("Команды: start, stop, status, help\n");
return 1;
}

char *command = argv[1];

if (strcmp(command, "start") == 0) {
printf("Запускаем систему...\n");
}
else if (strcmp(command, "stop") == 0) {
printf("Останавливаем систему...\n");
}
else if (strcmp(command, "status") == 0) {
printf("Система работает нормально\n");
}
else if (strcmp(command, "help") == 0) {
printf("Доступные команды: start, stop, status, help\n");
}
else {
printf("Неизвестная команда: %s\n", command);
printf("Используйте 'help' для списка команд\n");
}

return 0;
}

Практический пример: простой калькулятор

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void showUsage(char *programName) {
printf("Простой калькулятор\n");
printf("Использование: %s <число1> <операция> <число2>\n", programName);
printf("Операции: +, -, *, /\n");
printf("Пример: %s 10 + 5\n", programName);
}

int main(int argc, char *argv[])
{
// Проверяем количество аргументов
if (argc != 4) {
showUsage(argv[0]);
return 1;
}

// Получаем данные из аргументов
int num1 = atoi(argv[1]);
char *operation = argv[2];
int num2 = atoi(argv[3]);

int result;

// Определяем операцию
if (strcmp(operation, "+") == 0) {
result = num1 + num2;
printf("%d + %d = %d\n", num1, num2, result);
}
else if (strcmp(operation, "-") == 0) {
result = num1 - num2;
printf("%d - %d = %d\n", num1, num2, result);
}
else if (strcmp(operation, "*") == 0) {
result = num1 * num2;
printf("%d * %d = %d\n", num1, num2, result);
}
else if (strcmp(operation, "/") == 0) {
if (num2 == 0) {
printf("Ошибка: деление на ноль!\n");
return 1;
}
result = num1 / num2;
printf("%d / %d = %d\n", num1, num2, result);
}
else {
printf("Ошибка: неизвестная операция '%s'\n", operation);
showUsage(argv[0]);
return 1;
}

return 0;
}

Примеры использования:

./calc 15 + 7     # 15 + 7 = 22
./calc 20 - 8 # 20 - 8 = 12
./calc 6 * 4 # 6 * 4 = 24
./calc 15 / 3 # 15 / 3 = 5

Обработка опций

Программа с флагами

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
int verbose = 0; // Подробный вывод
int quiet = 0; // Тихий режим
char *filename = NULL;

// Обрабатываем все аргументы
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0) {
verbose = 1;
}
else if (strcmp(argv[i], "-q") == 0) {
quiet = 1;
}
else if (argv[i][0] != '-') {
// Это не опция, значит имя файла
filename = argv[i];
}
else {
printf("Неизвестная опция: %s\n", argv[i]);
return 1;
}
}

if (filename == NULL) {
printf("Ошибка: не указан файл\n");
return 1;
}

if (!quiet) {
printf("Обрабатываем файл: %s\n", filename);
}

if (verbose) {
printf("Режим подробного вывода включен\n");
printf("Размер имени файла: %lu символов\n", strlen(filename));
}

// Здесь была бы основная обработка файла
if (!quiet) {
printf("Файл обработан успешно\n");
}

return 0;
}

Примеры:

./processor file.txt           # Обычный режим
./processor -v file.txt # С подробным выводом
./processor -q file.txt # Тихий режим
./processor -v -q file.txt # Комбинация опций

Важные моменты

Распространенные ошибки
  • Забывают проверить argc — программа может упасть при обращении к несуществующему argv[i]
  • Путают порядок аргументов — помните, что argv[0] это имя программы
  • Не проверяют корректность данных — строка "abc" при atoi() даст 0
Рекомендации
  • Всегда проверяйте количество аргументов перед их использованием
  • Показывайте справку при неправильном запуске программы
  • Используйте понятные сообщения об ошибках
  • Проверяйте корректность числовых данных
Что запомнить
  • argc — количество всех аргументов (включая имя программы)
  • argv[0] — всегда имя программы
  • argv[1], argv[2], ... — параметры, переданные пользователем
  • Все аргументы приходят как строки, нужно преобразовывать в числа
  • Функция strcmp() используется для сравнения строк

Параметры командной строки делают ваши программы гибкими и удобными для пользователей. Они могут настраивать поведение программы, не изменяя её код.